home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
program
/
szadb1_4.zoo
/
src
/
adb1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-24
|
13KB
|
634 lines
/* Copyright (c) 1990 by Sozobon, Limited. Authors: Johann Ruegg, Don Dugger
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to redistribute it freely, with the
* following restrictions:
* 1) No charge may be made other than reasonable charges for reproduction.
* 2) Modified versions must be clearly marked as such.
* 3) The authors are not responsible for any harmful consequences
* of using this software, even if they result from defects in it.
*
* adb1.c
*/
/*
* Modifications:
* - added functions to handle MWC format symbol table and hooks to
* possibly add other formats
* - added functions for buffered output to external files
*
* Michal Jaegermann, May 1990
*
* - function setsym() modified to handle also extended format in
* which function name can be continued in the next symbol slot
* - added function extndsymb() which checks if symbols are using
* extended format
*
* Michal Jaegermann, January 1991
*/
#include <setjmp.h>
#include "adb.h"
#define IN_ADB1
#include "lang.h"
extern struct file binary;
extern long dot;
extern int dotoff;
extern long maxoff;
extern int ibase;
extern int lastc;
extern char sign;
extern int swidth;
extern jmp_buf jmpb;
extern int trid;
extern w_buf *trbuf;
extern char *trname;
getfmt (fmt)
register char *fmt;
{
int in_string = 0;
while ((*fmt = getchr (in_string)) != '\n') {
if ('"' == *fmt)
in_string = !in_string;
fmt++;
}
*fmt = '\0';
PUSHC ('\n');
return;
}
long
getdot (d, n)
long d;
int n;
{
long l;
l = dot;
if (n == 2)
l &= 0xffff;
else if (n == 1)
l &= 0xff;
return (l);
}
#ifdef GONER
unsigned char
getb (fp)
struct file *fp;
{
long getn ();
return (getn (dot + dotoff, 1));
}
#endif
unsigned int
getwd ()
{
long getn ();
return (getn (dot + dotoff, 2));
}
putn (v, d, n)
long v, d;
int n;
{
union {
int i;
long l;
} no, val;
long b;
register int o;
char *p, *s;
b = d >> LOGBS;
o = d & (BSIZE - 1);
switch (n) {
case 2:
p = (char *) (&no.i);
val.i = v;
s = (char *) (&val.i);
break;
case 4:
p = (char *) (&no.l);
val.l = v;
s = (char *) (&val.l);
break;
}
rdsub (d, p, n, 0);
dotoff += n;
switch (n) {
case 2:
bcopy (s, p, n);
break;
case 4:
bcopy (s, p, n);
break;
}
wrsub (p, d, n, 0);
return;
}
long
getn (d, n)
unsigned long d;
int n;
{
unsigned long b, no;
register unsigned int o;
char *p;
b = d >> LOGBS;
o = d & (BSIZE - 1);
rdsub (d, &b, n, 0);
p = (char *) &b;
dotoff += n;
switch (n) {
case 1:
no = *p;
break;
case 2:
no = *(int *) p;
break;
case 4:
no = *(long *) p;
break;
}
return (no);
}
puto (n, s)
unsigned long n;
int s;
{
if (n > 0)
puto ((n >> 3) & 0x1fffffff, --s);
else
while (s-- > 0)
putchr (' ');
putchr ((char) ((n & 7) + '0'));
return;
}
putd (n, s)
long n;
int s;
{
if (n < 0) {
s--;
n = -n;
if (n < 0) {
while (s-- > 0)
putchr (' ');
putchr ('?');
return;
}
else
sign = '-';
}
if (n > 9)
putd (n / 10, --s);
else
while (s-- > 0)
putchr (' ');
if (sign) {
putchr (sign);
sign = 0;
}
putchr ((char) ((n % 10) + '0'));
return;
}
putx (n, s)
unsigned long n;
int s;
{
if (n > 0xf)
putx ((n >> 4) & 0xfffffff, --s);
else {
while (s-- > 0)
putchr (' ');
}
putchr ("0123456789abcdef"[n & 0xf]);
return;
}
prtn (n, s)
long n;
int s;
{
switch (ibase) {
case 8:
puto (n, s);
break;
case 10:
putd (n, s);
break;
default:
case 16:
putx (n, s);
break;
}
return;
}
prt (s)
register char *s;
{
while (*s)
putchr (*s++);
return;
}
relsym ()
{
register struct symbol *sp;
extern struct basepg *bpage;
sp = binary.symptr;
while (sp) {
sp->value += (long) bpage->p_tbase;
sp = sp->next;
}
}
mwsetsym (fid, ssize)
/* read symbol table in MWC format */
int fid;
long ssize;
{
struct mwfilsym sym;
char ct;
if (0 != (ssize % sizeof(sym))) {
if (ssize <= 0x30L)
return 0;
lseek (fid, 0x30L, 1); /* skip some really not-symbol stuff */
ssize -= 0x30L;
}
do {
if (read (fid, &sym, sizeof (sym)) != sizeof (sym))
return -1;
if (sym.flag & 0x1000) { /* global data */
ct = sym.sval.got[0];
sym.sval.got[0] = sym.sval.got[1];
sym.sval.got[1] = ct;
ct = sym.sval.got[2];
sym.sval.got[2] = sym.sval.got[3];
sym.sval.got[3] = ct;
if (0 == addsym (&binary.symptr, sym.name, sym.sval.value))
break;
}
} while (0 < (ssize -= sizeof (sym)));
return 0;
} /* mwsetsym */
setsym (fid, ssize)
/* Read symbol table in Alcyon format - used by Sozobon as well. */
/* This function modified to handle also symbol tables where symbol */
/* name possibly extends into the next symbol slot; only when */
/* signalled by S_LNAM flag, otherwise backward compatible. */
int fid;
long ssize;
{
register int extsymbs;
struct filsym sym; /* dummy for #defines - Sozobon doesn't know what
to do with sizeof(struct filsym) */
#define SYMSPAN sizeof(sym)
#define NAMSIZE sizeof(sym.name)
struct {
char xname[NAMSIZE + SYMSPAN];
short xflag;
long xvalue;
} xsym;
extsymbs = (22 == swidth);
do {
if ((read (fid, &xsym, NAMSIZE) != NAMSIZE) ||
(read (fid, (char *)(&xsym) + NAMSIZE + SYMSPAN, SYMSPAN - NAMSIZE)
!= SYMSPAN - NAMSIZE))
return -1;
if (0 >= (ssize -= SYMSPAN)) {
xsym.xflag &= ~S_LNAM;
}
if (extsymbs && (S_LNAM == (xsym.xflag & S_LNAM))) {
if (read (fid, (char *)(&xsym) + NAMSIZE, SYMSPAN) != SYMSPAN)
return -1;
ssize -= SYMSPAN;
}
else {
xsym.xname[NAMSIZE] = '\0';
}
if ((xsym.xflag & S_EXT) &&
(xsym.xflag & (S_DATA | S_TEXT | S_BSS))) {
if (0 == addsym (&binary.symptr, xsym.xname, xsym.xvalue))
break;
}
} while (ssize > 0);
return 0;
} /* setsym */
#undef SYMSPAN
#undef NAMSIZE
addsym (spp, name, value)
struct symbol **spp;
char *name;
long value;
{
register char *cp, *cps, *cptr;
long v;
struct symbol *sp;
char *malloc ();
struct symbol *p;
int msize;
v = value;
sp = *spp;
while (sp && (sp->value <= v)) {
spp = &sp->next;
sp = *spp;
}
cps = name;
cp = cps + swidth; /* max symbol size */
while ( *cps && (cps < cp))
cps++;
cp = name;
msize = sizeof (*p) + (int)(cps - cp) + 1; /* need a space for '\0' */
if ((p = (struct symbol *) malloc (msize)) == 0) {
/* prtf("can't allocate %i bytes for symbol\n", sizeof(*p)); */
prtf (M1, msize);
return 0;
}
*spp = p;
p->next = sp;
p->value = v;
cptr = p->name;
while (cp < cps)
*cptr++ = *cp++;
*cptr = '\0';
return 1;
}
int
extndsymb(fid, ssize)
/* check if any symbol in a file is in an extended format */
int fid;
long ssize;
{
register int extended;
struct filsym sym;
long position;
extern long tell();
position = tell(fid);
do {
if (read (fid, &sym, sizeof (sym)) != sizeof (sym))
break;
if (extended = (S_LNAM